package com.renfei.cameralibrary.presenter;

import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.SurfaceTexture;
import android.opengl.EGLContext;
import android.os.Environment;
import android.util.Log;

import androidx.annotation.NonNull;

import com.cgfay.uitls.utils.BitmapUtils;
import com.cgfay.uitls.utils.BrightnessUtils;
import com.cgfay.uitls.utils.FileUtils;
import com.renfei.cameralibrary.camera.CameraController;
import com.renfei.cameralibrary.camera.CameraParam;
import com.renfei.cameralibrary.camera.ICameraController;
import com.renfei.cameralibrary.camera.listener.PreviewCallback;
import com.renfei.cameralibrary.encoder.MediaAudioEncoder;
import com.renfei.cameralibrary.encoder.MediaEncoder;
import com.renfei.cameralibrary.encoder.MediaMuxerWrapper;
import com.renfei.cameralibrary.encoder.MediaVideoEncoder;
import com.renfei.cameralibrary.fragment.CameraPreviewFragment;
import com.renfei.cameralibrary.listener.OnCaptureListener;
import com.renfei.cameralibrary.camera.listener.OnFrameAvailableListener;
import com.renfei.cameralibrary.camera.listener.OnSurfaceTextureListener;
import com.renfei.cameralibrary.listener.OnPreviewCaptureListener;
import com.renfei.cameralibrary.render.CameraRenderer;
import com.renfei.cameralibrary.utils.PathConstraints;
import com.renfei.cameralibrary.utils.VideoFileUtils;
import com.renfei.filterlibrary.glfilter.color.bean.DynamicColor;
import com.renfei.filterlibrary.glfilter.resource.FilterHelper;
import com.renfei.filterlibrary.glfilter.resource.ResourceHelper;
import com.renfei.filterlibrary.glfilter.resource.ResourceJsonCodec;
import com.renfei.filterlibrary.glfilter.resource.bean.ResourceData;
import com.renfei.filterlibrary.glfilter.resource.bean.ResourceType;
import com.renfei.medialibrary.FFmpegPlayer;
import com.renfei.medialibrary.SpeedMode;
import com.renfei.medialibrary.listener.OnPlayerCompleteListener;
import com.renfei.medialibrary.listener.OnPlayerErrorListener;
import com.renfei.medialibrary.listener.OnPlayerLoadListener;
import com.renfei.medialibrary.listener.OnPlayerParparedListener;
import com.renfei.medialibrary.listener.OnPlayerStatusChangeListener;
import com.renfei.medialibrary.recorder.AudioParams;
import com.renfei.medialibrary.recorder.VideoParams;
import com.renfei.medialibrary.util.MuteEnum;

import java.io.File;
import java.io.FileFilter;
import java.io.IOException;

/**
 * 相机预览的presenter
 */
public class CameraPreviewPresenter extends PreviewPresenter<CameraPreviewFragment> implements
        PreviewCallback, OnFrameAvailableListener, OnSurfaceTextureListener,
        OnCaptureListener,//相机拍摄监听
//        OnRecordStateListener

        OnPlayerParparedListener,
        OnPlayerLoadListener,
        OnPlayerErrorListener,
        OnPlayerStatusChangeListener,
        OnPlayerCompleteListener {

    private static final String TAG = "CameraPreviewPresenter";

    public static final int SECOND_IN_US = 1000000;
    // 预览参数
    private CameraParam mCameraParam;
    private Activity mActivity;
    // 相机接口
    private ICameraController mCameraController;
    // 渲染器
    private final CameraRenderer mCameraRenderer;

    //当前滤镜索引
    // 当前索引
    private int mFilterIndex = 0;


    // 背景音乐
    private String mMusicPath;
    /**
     * 视频录制
     */
    // 音视频参数
    private final VideoParams mVideoParams;
    private final AudioParams mAudioParams;
    // 录制操作开始
    private boolean mOperateStarted = false;
    // 当前录制进度
    private float mCurrentProgress;
    // 最大时长
    private long mMaxDuration;
    // 剩余时长
    private long mRemainDuration;
    // 视频录制器
//    private BaseMediaRecorder mediaRecorder;
    // 录制音频信息
//    private RecordInfo mAudioInfo;
    // 录制视频信息
//    private RecordInfo mVideoInfo;

    //视频录制器
    private MediaMuxerWrapper mMuxer;

    //音乐播放器
    private FFmpegPlayer minePlayer;
    private String mOutputPath;
    private boolean isPlayerPreapred = false;

    public CameraPreviewPresenter(CameraPreviewFragment target) {
        super(target);
        mCameraParam = CameraParam.getInstance();
        mCameraRenderer = new CameraRenderer(this);

        // 视频录制器
        mVideoParams = new VideoParams();
        mAudioParams = new AudioParams();


        minePlayer = new FFmpegPlayer();
        minePlayer.setVolume(50);
        minePlayer.setMute(MuteEnum.MUTE_CENTER);

        minePlayer.setOnPlayerParparedListener(this);
        minePlayer.setOnPlayerErrorListener(this);
        minePlayer.setOnPlayerErrorListener(this);
        minePlayer.setOnPlayerCompleteListener(this);
        minePlayer.setOnPlayerStatusChangeListener(this);
    }

    public void onAttach(Activity activity) {
        Log.e(TAG, "onAttach: ");
        mActivity = activity;

        mVideoParams.setVideoPath(PathConstraints.getVideoTempPath(mActivity));
        mAudioParams.setAudioPath(PathConstraints.getAudioTempPath(mActivity));

        mCameraRenderer.initRenderer();

        mCameraController = new CameraController(mActivity);
        mCameraController.setPreviewCallback(this);
        mCameraController.setOnFrameAvailableListener(this);
        mCameraController.setOnSurfaceTextureListener(this);

        if (BrightnessUtils.getSystemBrightnessMode(mActivity) == 1) {
            mCameraParam.brightness = -1;
        } else {
            mCameraParam.brightness = BrightnessUtils.getSystemBrightness(mActivity);
        }
    }

    @Override
    public void onCreate() {
        super.onCreate();
        Log.e(TAG, "onCreate: ");
    }

    @Override
    public void onStart() {
        super.onStart();
        Log.e(TAG, "onStart: ");
    }

    @Override
    public void onResume() {
        super.onResume();
        Log.e(TAG, "onResume: ");
        openCamera();
        mCameraParam.captureCallback = this;
    }

    @Override
    public void onPause() {
        Log.e(TAG, "onPause: ");
        super.onPause();
        mCameraRenderer.onPause();
        closeCamera();
        mCameraParam.captureCallback = null;
    }

    @Override
    public void onStop() {
        super.onStop();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();

    }

    public void onDetach() {
        mActivity = null;
        mCameraRenderer.destroyRenderer();
    }


    @NonNull
    @Override
    public Context getContext() {
        return mActivity;
    }

    @Override
    public void onBindSharedContext(EGLContext context) {
        Log.d(TAG, "onBindSharedContext: ");
        mVideoParams.setEglContext(context);
    }

    @Override
    public void onRecordFrameAvailable(int texture, long timestamp) {
        if (mOperateStarted) {
            mMuxer.frameAvailable(texture, timestamp);
        }
    }

    //***********预览SurfaceTexture监听************************************************************************************
    @Override
    public void onSurfaceCreated(SurfaceTexture surfaceTexture) {
        mCameraRenderer.onSurfaceCreated(surfaceTexture);
    }

    @Override
    public void onSurfaceChanged(int width, int height) {
        mCameraRenderer.onSurfaceChanged(width, height);
    }

    @Override
    public void onSurfaceDestroyed() {
        mCameraRenderer.onSurfaceDestroyed();
    }
    //****************滤镜部分******************************************************************************

    @Override
    public void changeResource(@NonNull ResourceData resourceData) {
        ResourceType type = resourceData.type;
        String unzipFolder = resourceData.unzipFolder;
        if (type == null) {
            return;
        }
        try {
            switch (type) {
                //滤镜
                case FILTER:
                    String folderPath = ResourceHelper.getResourceDirectory(mActivity) + File.separator + unzipFolder;
                    DynamicColor color = ResourceJsonCodec.decodeFilterData(folderPath);
                    mCameraRenderer.changeResource(color);
                    break;
                //贴纸
                case STICKER:
                    break;
                //多种结果混合
                case MULTI:
                    break;
                //所有数据均为空
                case NONE:
                    break;
                default:
                    break;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void changeDynamicFilter(DynamicColor color) {
        mCameraRenderer.changeFilter(color);
    }

    @Override
    public void changeDynamicFilter(int filterIndex) {
        if (mActivity == null) {
            return;
        }
        String folderPath = FilterHelper.getFilterDirectory(mActivity) + File.separator
                + FilterHelper.getFilterList().get(filterIndex).unzipFolder;
        DynamicColor color = null;
        if (!FilterHelper.getFilterList().get(filterIndex).unzipFolder.equalsIgnoreCase("none")) {
            try {
                color = ResourceJsonCodec.decodeFilterData(folderPath);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        mCameraRenderer.changeFilter(color);
    }

    @Override
    public int previewFilter() {
        mFilterIndex--;
        if (mFilterIndex < 0) {
            int count = FilterHelper.getFilterList().size();
            mFilterIndex = count > 0 ? count - 1 : 0;
        }
        changeDynamicFilter(mFilterIndex);
        return mFilterIndex;
    }

    @Override
    public int nextFilter() {
        mFilterIndex++;
        mFilterIndex = mFilterIndex % FilterHelper.getFilterList().size();
        changeDynamicFilter(mFilterIndex);
        return mFilterIndex;
    }

    @Override
    public int getFilterIndex() {
        return mFilterIndex;
    }

    @Override
    public void showCompare(boolean enable) {
        mCameraParam.showCompare = enable;
    }


    //***********相机监听回调************************************************************************************
    @Override
    public void onFrameAvailable(SurfaceTexture surfaceTexture) {
//        Log.e(TAG, "onFrameAvailable: ");
    }

    @Override
    public void onSurfaceTexturePrepared(@NonNull SurfaceTexture surfaceTexture) {
        mCameraRenderer.bindInputSurfaceTexture(surfaceTexture);
    }

    @Override
    public void onPreviewFrame(byte[] data) {
//        Log.d(TAG, "onPreviewFrame: ");
        mCameraRenderer.requestRender();
    }


    @Override
    public void takePicture() {
        mCameraRenderer.takePicture();
    }

    @Override
    public void switchCamera() {
        mCameraController.switchCamera();
    }


    //****************视频录制******************************************************************************

    @Override
    public void startRecord() {
        Log.e(TAG, "startRecord: ");
        if (mOperateStarted) {
            return;
        }
        try {
            mOutputPath = VideoFileUtils.getCaptureFile(Environment.DIRECTORY_MOVIES, ".mp4").toString();

            mMuxer = new MediaMuxerWrapper(mOutputPath);

            new MediaVideoEncoder(mMuxer, mVideoParams, mMediaEncoderListener);
            new MediaAudioEncoder(mMuxer, mAudioParams, mMediaEncoderListener);

            if (isPlayerPreapred) {
                minePlayer.startPlay();
            }
            mMuxer.prepare();
            mMuxer.startRecording();
            mOperateStarted = true;
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void stopRecord() {
        Log.e(TAG, "stopRecord: ");
        if (!mOperateStarted) {
            return;
        }
        mOperateStarted = false;

        if (null != minePlayer) {
            minePlayer.stop();
            isPlayerPreapred = false;
            minePlayer = null;
        }

        if (mMuxer != null) {
            mMuxer.stopRecording();
            mMuxer = null;
            // you should not wait here
        }
    }

    @Override
    public void cancelRecord() {
        stopRecord();
    }

    @Override
    public boolean isRecording() {
        return (mOperateStarted);
    }


    @Override
    public void setRecordSeconds(int seconds) {
        mMaxDuration = mRemainDuration = seconds * SECOND_IN_US;
        mVideoParams.setMaxDuration(mMaxDuration);
        mAudioParams.setMaxDuration(mMaxDuration);
    }

    @Override
    public void setSpeedMode(SpeedMode mode) {
        mVideoParams.setSpeedMode(mode);
        mAudioParams.setSpeedMode(mode);
    }

    @Override
    public void setMusicPath(String path) {

        mMusicPath = path;

        minePlayer.setSource(mMusicPath);
        minePlayer.parpared();
    }


    //****************相机打开关闭******************************************************************************

    /**
     * 打开相机
     */
    private void openCamera() {
        mCameraController.openCamera();
        calculateImageSize();
    }

    /**
     * 关闭相机
     */
    private void closeCamera() {
        mCameraController.closeCamera();
    }


    /**
     * 计算imageView 的宽高
     */
    private void calculateImageSize() {
        int width;
        int height;
        if (mCameraController.getOrientation() == 90 || mCameraController.getOrientation() == 270) {
            width = mCameraController.getPreviewHeight();
            height = mCameraController.getPreviewWidth();
        } else {
            width = mCameraController.getPreviewWidth();
            height = mCameraController.getPreviewHeight();
        }
        mVideoParams.setVideoSize(width, height);
        mCameraRenderer.setTextureSize(width, height);
    }

    //******************相机拍摄监听****************************************************************************
    @Override
    public void onCapture(Bitmap bitmap) {
        Log.e(TAG, "onCapture: ");
        String filePath = PathConstraints.getImageCachePath(mActivity);
        Log.e(TAG, "onCapture: saveBitmap path " + filePath);
        BitmapUtils.saveBitmap(filePath, bitmap);

        if (mCameraParam.captureListener != null) {
            mCameraParam.captureListener.onMediaSelectedListener(filePath, OnPreviewCaptureListener.MediaTypePicture);
        }
        /**
         * 添加代码
         */
        mCameraParam.touchTake = false;
    }


    private int stopCount = 0;

    /**
     * callback methods from encoder
     */
    private final MediaEncoder.MediaEncoderListener mMediaEncoderListener = new MediaEncoder.MediaEncoderListener() {
        @Override
        public void onPrepared(final MediaEncoder encoder) {
            Log.e(TAG, "mMediaEncoderListener: onPrepared");
        }

        @Override
        public void onStopped(final MediaEncoder encoder) {
            Log.e(TAG, "mMediaEncoderListener: onStopped");
            stopCount++;
            if (stopCount % 2 == 0) {
                if (mCameraParam.captureListener != null) {
                    mCameraParam.captureListener.onMediaSelectedListener(mOutputPath, OnPreviewCaptureListener.MediaTypeVideo);
                }
            }
        }
    };


    @Override
    public void onComplete() {
    }

    @Override
    public void onLoad(boolean load) {

    }

    @Override
    public void onParpared() {
        Log.e(TAG, "onParpared: ");
        isPlayerPreapred = true;
    }

    @Override
    public void onPause(boolean isPause) {

    }

    @Override
    public void onError(int code, String msg) {

    }
}
